/*function extend2(Child, Parent) {
     var F = function(){};
     F.prototype = Parent.prototype;
     Child.prototype = new F();
     Child.prototype.constructor = Child;
     Child.uber = Parent.prototype;//super
 }*/

function extend(subConstructor,superConstructor){
    subConstructor.prototype = Object.create(superConstructor.prototype,{
        constructor:{
            value:subConstructor,
            enumerable:false,
            writable:true,
            configurable:true
        }
    });
}

function fatherClass(name,age){
    this.name = name;
    this.age = age;
}
fatherClass.prototype.say = function(){
    console.log(" the say method of father class");
};

function anotherSon(name,age){
    this.say = function(){
        console.log("i am anotherSon");
    }
}
extend(anotherSon,fatherClass);
// anotherSon.prototype = new fatherClass();

function threeSon(name,age){
    this.say = function(){
        console.log("i am threeSon");
    }
}
extend(threeSon,fatherClass);
// threeSon.prototype = new fatherClass();

function littleSon(name,age){
    // console.log(this);
    fatherClass.call(this,name,age);
    this.color = '#ffffff';
}
extend(littleSon,fatherClass);
// littleSon.prototype = new fatherClass();

function yes_or_no(cls){
    if(cls instanceof fatherClass){
        cls.say();
    }
}

var objanotherSon = new anotherSon();
var objthreeSon = new threeSon();
var litSon = new littleSon('kk',12);
yes_or_no(objanotherSon);
yes_or_no(objthreeSon);
yes_or_no(litSon);
console.log(objanotherSon instanceof fatherClass);
console.log(objthreeSon instanceof fatherClass);
console.log(litSon instanceof fatherClass);
console.log(litSon.name,'  ',litSon.age,'  ',litSon.color);




/**
 * RoulerPool class
 * @constructor
 */
function RoulerPool() {
    var _container = {};

    /*
     * role:Rouler
     */
    this.regRouler = function(role){
        if(role.roulerName=='' && !(role instanceof Rouler))return;
        if(_container.hasOwnProperty(role.roulerName))return;
        _container[role.roulerName] = role;
    };
    /*
     * FROM:Rouler,TO:String, signal:String, extraParam:Object
     */
    this.transmit = function (FROM,TO,signal,extraParem) {
        if(!_container.hasOwnProperty(TO))return;
        if(!(FROM instanceof Rouler))return;
        _container[TO].recevieSignal(FROM.roulerName,signal,extraParem);
    };
    /*
     * roulerName:String
     */
    this.removeRouler = function(roulerName){
        if(_container.hasOwnProperty(roulerName)) delete _container[roulerName];
    }
}

/**
 * Rouler class
 *
 * @param name
 * @param rolePool
 * @constructor
 */
function Rouler(name,rolePool) {
    this.roulerName= name;
    this.roulerPool= rolePool;
}
Rouler.prototype.setRoulerName = function (name) {
    this.roulerName = name;
};
Rouler.prototype.setRoulerPool = function(rolePool){
    if(!(rolePool instanceof RoulerPool))throw new Error('Parameter type is wrong!');
    this.roulerPool = rolePool;
};
//target:String, signal:String, extraParam:Object
Rouler.prototype.sendSignal = function (tagert,signal,extraParam) {
    if(this.roulerPool instanceof RoulerPool){
        this.roulerPool.transmit(this,tagert,signal,extraParam);
    }
};
//From:String, signal:String, extraParam:Object
Rouler.prototype.recevieSignal = function (form, signal, extraParam) {
    console.log('I Rouler recevieSignal');
};
/**
 * RoulerObject extends for Rouler class
 *
 * @param name
 * @param rolePool
 * @constructor
 */
function RoulerObject(name,rolePool){
    Rouler.call(this,name,rolePool);
}
/*RoulerObject.prototype = new Rouler();
RoulerObject.prototype.constructor = RoulerObject;*/
extend(RoulerObject,Rouler);
RoulerObject.prototype.init = function () {

};
RoulerObject.prototype.create = function () {

};
RoulerObject.prototype.delete = function () {
    console.log('RoulerObject delete!!');
};

/**
 *class end ---------------------------------------------------
 */


var roulerPool = new RoulerPool();


function App1(name,rolePool) {
    RoulerObject.call(this,name,rolePool);
    this.recevieSignal = function (form, signal, extraParam) {
        console.log(form,signal);
    };
}
extend(App1,RoulerObject);

function App2(name,rolePool) {
    Rouler.call(this,name,rolePool);
    this.recevieSignal = function (form, signal, extraParam) {
        console.log(form,signal);
    };
}
extend(App2,Rouler);


var a1 = new App1('zhang',roulerPool);
var a2 = new App2('huang',roulerPool);
roulerPool.regRouler(a1);
roulerPool.regRouler(a2);
a1.sendSignal('huang','hello huang');
a2.sendSignal('zhang','call zhang');
a1.delete();
